﻿using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MangosRestarter
{
    public partial class MainForm : Form
    {
        private NotifyIcon trayIcon;
        private ContextMenuStrip trayMenu;
        private FileSystemWatcher configWatcher;

        private readonly ServerWatcher worldWatcher;
        private readonly ServerWatcher realmWatcher;

        private bool areWindowsHidden = false;

        public MainForm()
        {
            InitializeComponent();
            InitTray();
            SetupConfigWatcher();

            ConfigHelper.EnsureDefaultConfig();
            worldWatcher = new ServerWatcher(ConfigHelper.WorldServerPath, "世界服务器", OnLog);
            realmWatcher = new ServerWatcher(ConfigHelper.RealmServerPath, "登录服务器", OnLog);
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            CleanupResources();
        }

        private void CleanupResources()
        {
            try
            {
                MySqlMonitor.StopMonitoring();
                configWatcher?.Dispose();
                trayIcon?.Dispose();
                trayMenu?.Dispose();
                worldWatcher?.Stop();
                realmWatcher?.Stop();
            }
            catch (Exception ex)
            {
                Logger.Write($"资源清理失败: {ex.Message}");
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                // 检查三个进程是否都未运行
                bool noWorldProcess = Process.GetProcessesByName("mangosd").Length == 0;
                bool noRealmProcess = Process.GetProcessesByName("realmd").Length == 0;
                bool noMySqlProcess = !MySqlChecker.IsRunning();

                // 如果三个进程都未运行，直接关闭程序
                if (noWorldProcess && noRealmProcess && noMySqlProcess)
                {
                    trayIcon.Visible = false;
                    CleanupResources();
                    Application.Exit();
                    return;
                }
                e.Cancel = true;

                using (var dlg = new ExitConfirmDlg())
                {
                    var result = dlg.ShowDialog(this);

                    if (result == DialogResult.Yes)
                    {
                        if (areWindowsHidden)
                        {
                            NativeMethods.ShowAllMonitoredProcessWindows();
                            OnLog("已恢复所有服务器窗口显示");
                        }

                        trayIcon.Visible = false;
                        CleanupResources();
                        Application.Exit();
                    }
                    else if (result == DialogResult.No)
                    {
                        Hide();
                        HideServerWindows();
                    }
                }
            }
            else
            {
                if (areWindowsHidden)
                {
                    NativeMethods.ShowAllMonitoredProcessWindows();
                }

                CleanupResources();
                Application.Exit();
            }
        }

        private void HideServerWindows()
        {
            if (!areWindowsHidden)
            {
                NativeMethods.HideAllMonitoredProcessWindows();
                areWindowsHidden = true;
                OnLog("已隐藏所有服务器窗口（包括MySQL的cmd窗口）");
                trayIcon.Text = "MangosRestarter - 窗口已隐藏";

                // 额外隐藏可能存在的其他cmd窗口
                HideCommandWindows();
            }
        }

        private void ShowServerWindows()
        {
            if (areWindowsHidden)
            {
                NativeMethods.ShowAllMonitoredProcessWindows();
                areWindowsHidden = false;
                OnLog("已显示所有服务器窗口（包括MySQL的cmd窗口）");
                UpdateStatusDisplay();

                // 额外显示可能存在的其他cmd窗口
                ShowCommandWindows();
            }
        }

        /// <summary>
        /// 额外隐藏所有cmd窗口（确保MySQL的cmd窗口被隐藏）
        /// </summary>
        private void HideCommandWindows()
        {
            try
            {
                var cmdProcesses = Process.GetProcessesByName("cmd");
                foreach (var process in cmdProcesses)
                {
                    try
                    {
                        // 检查cmd窗口的标题，如果是MySQL相关的就隐藏
                        if (!string.IsNullOrEmpty(process.MainWindowTitle) &&
                            (process.MainWindowTitle.Contains("MySQL") || process.MainWindowTitle.Contains("mysqld")))
                        {
                            NativeMethods.SetProcessWindowsVisibility(process, false);
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Write($"隐藏cmd窗口失败: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Write($"查找cmd进程失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 额外显示所有cmd窗口
        /// </summary>
        private void ShowCommandWindows()
        {
            try
            {
                var cmdProcesses = Process.GetProcessesByName("cmd");
                foreach (var process in cmdProcesses)
                {
                    try
                    {
                        NativeMethods.SetProcessWindowsVisibility(process, true);
                    }
                    catch (Exception ex)
                    {
                        Logger.Write($"显示cmd窗口失败: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Write($"查找cmd进程失败: {ex.Message}");
            }
        }

        private void SetupConfigWatcher()
        {
            try
            {
                configWatcher = new FileSystemWatcher
                {
                    Path = AppDomain.CurrentDomain.BaseDirectory,
                    Filter = "MangosRestarter.conf",
                    NotifyFilter = NotifyFilters.LastWrite
                };

                configWatcher.Changed += (s, e) =>
                {
                    Thread.Sleep(100);
                    LoadConfig();
                    OnLog("配置文件已重新加载");
                };

                configWatcher.EnableRaisingEvents = true;
                OnLog("配置文件监控已启动: MangosRestarter.conf");
            }
            catch (Exception ex)
            {
                OnLog($"配置文件监控启动失败: {ex.Message}");
            }
        }

        private void LoadConfig()
        {
            var cfg = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "MangosRestarter.conf");
            if (!File.Exists(cfg))
            {
                OnLog("配置文件不存在，使用默认配置");
                return;
            }

            try
            {
                bool worldExecLoaded = false;
                bool realmExecLoaded = false;
                int intervalLoaded = 0;

                foreach (var line in File.ReadAllLines(cfg))
                {
                    if (string.IsNullOrWhiteSpace(line) || line.Trim().StartsWith("#"))
                        continue;

                    var kv = line.Split('=');
                    if (kv.Length < 2) continue;

                    var k = kv[0].Trim();
                    var v = kv[1].Trim();

                    if (k == "WorldServerPath")
                    {
                        worldWatcher.Executable = v;
                        worldExecLoaded = true;
                    }
                    else if (k == "RealmServerPath")
                    {
                        realmWatcher.Executable = v;
                        realmExecLoaded = true;
                    }
                    else if (k == "CheckIntervalMs" && int.TryParse(v, out var ci))
                    {
                        ServerWatcher.CheckIntervalMs = ci;
                        intervalLoaded = ci;
                    }
                }

                OnLog($"服务器配置加载完成");
                OnLog($"世界服务器: {worldExecLoaded}, 登录服务器: {realmExecLoaded}, 检测间隔: {intervalLoaded} 毫秒");
            }
            catch (Exception ex)
            {
                OnLog($"配置文件加载失败: {ex.Message}");
            }
        }

        private void OnLog(string text)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<string>(OnLog), text);
                return;
            }

            UpdateStatusDisplay();

            // 根据文本内容判断颜色
            Color textColor = Color.Black;
            if (text.Contains("[ERROR]") || text.Contains("失败") || text.Contains("错误"))
            {
                textColor = Color.Red;
            }
            else if (text.Contains("[WARNING]") || text.Contains("警告"))
            {
                textColor = Color.Orange;
            }
            else if (text.Contains("成功") || text.Contains("启动完成"))
            {
                textColor = Color.Green;
            }

            // 添加带颜色的日志
            txtLog.SelectionStart = txtLog.TextLength;
            txtLog.SelectionLength = 0;
            txtLog.SelectionColor = textColor;
            txtLog.AppendText($"[{DateTime.Now:HH:mm:ss}] {text}\r\n");
            txtLog.SelectionColor = txtLog.ForeColor;
            txtLog.ScrollToCaret();

            Logger.Write(text);
        }

        private void UpdateStatusDisplay()
        {
            try
            {
                string worldStatus = Process.GetProcessesByName("mangosd").Length > 0 ? "运行中" : "已停止";
                string realmStatus = Process.GetProcessesByName("realmd").Length > 0 ? "运行中" : "已停止";
                string mysqlStatus = MySqlChecker.IsRunning() ? "运行中" : "已停止";

                lblStatus.Text = $"状态: 世界服务器({worldStatus}) | 登录服务器({realmStatus}) | MySQL({mysqlStatus})";
                this.Text = $"MangosRestarter - 世界:{worldStatus} 登录:{realmStatus} MySQL:{mysqlStatus}";
                trayIcon.Text = $"MangosRestarter - 世界:{worldStatus} 登录:{realmStatus}";
            }
            catch (Exception ex)
            {
                Logger.Write($"更新状态显示失败: {ex.Message}");
            }
        }

        private void InitTray()
        {
            trayMenu = new ContextMenuStrip();
            trayMenu.Items.Add("显示主窗口", null, ShowClick);
            trayMenu.Items.Add(new ToolStripSeparator());

            var toggleWindowsItem = new ToolStripMenuItem("显示服务器窗口");
            toggleWindowsItem.Click += ToggleWindowsClick;
            trayMenu.Items.Add(toggleWindowsItem);

            trayMenu.Items.Add(new ToolStripSeparator());
            trayMenu.Items.Add("重启世界服务器", null, (s, e) => worldWatcher.Restart());
            trayMenu.Items.Add("重启登录服务器", null, (s, e) => realmWatcher.Restart());
            trayMenu.Items.Add(new ToolStripSeparator());
            trayMenu.Items.Add("退出", null, ExitClick);

            trayIcon = new NotifyIcon
            {
                Text = "MangosRestarter - 监控中",
                Icon = SystemIcons.Application,
                ContextMenuStrip = trayMenu,
                Visible = true
            };
            trayIcon.DoubleClick += ShowClick;
        }

        private void ToggleWindowsClick(object sender, EventArgs e)
        {
            if (areWindowsHidden)
            {
                ShowServerWindows();
                ((ToolStripMenuItem)sender).Text = "隐藏服务器窗口";
            }
            else
            {
                HideServerWindows();
                ((ToolStripMenuItem)sender).Text = "显示服务器窗口";
            }
        }

        private void ShowClick(object sender, EventArgs e)
        {
            ShowServerWindows();
            Show();
            WindowState = FormWindowState.Normal;
            BringToFront();
            UpdateTrayMenuText();
        }

        private void UpdateTrayMenuText()
        {
            foreach (ToolStripItem item in trayMenu.Items)
            {
                if (item is ToolStripMenuItem menuItem && (menuItem.Text == "显示服务器窗口" || menuItem.Text == "隐藏服务器窗口"))
                {
                    menuItem.Text = areWindowsHidden ? "显示服务器窗口" : "隐藏服务器窗口";
                    break;
                }
            }
        }

        private void ExitClick(object sender, EventArgs e)
        {
            if (areWindowsHidden)
            {
                NativeMethods.ShowAllMonitoredProcessWindows();
                OnLog("已恢复所有服务器窗口显示");
            }

            trayIcon.Visible = false;
            CleanupResources();
            Application.Exit();
        }
        private void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                LoadConfig();
                ConfigHelper.LoadSettings();

                if (!ConfigHelper.ValidateConfig(out string configError))
                {
                    OnLog($"[ERROR] 配置验证失败: {configError}");
                    MessageBox.Show(configError, "配置错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // 检查MySQL状态
                bool mySqlRunning = MySqlChecker.IsRunning();

                if (ConfigHelper.StartMySql)
                {
                    OnLog("正在启动MySQL...");
                    bool mysqlStarted = false;
                    string error = null;

                    mysqlStarted = MySqlStarter.TryStartWithVisibleConsole(out error);

                    if (!mysqlStarted)
                    {
                        OnLog($"[ERROR] MySQL启动失败: {error}");
                        MessageBox.Show($"MySQL启动失败: {error}", "启动错误",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    OnLog("MySQL启动成功");
                    mySqlRunning = true; // 确保状态更新
                }
                else
                {
                    if (!mySqlRunning)
                    {
                        OnLog("[ERROR] 配置禁止启动MySQL，且未检测到MySQL进程");
                        MessageBox.Show("MySQL未运行且配置禁止自动启动。请手动启动MySQL后再运行程序。",
                            "MySQL未运行", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return; // 直接返回，不启动其他服务器
                    }
                    else
                    {
                        OnLog("MySQL已在运行中");
                    }
                }

                // 只有MySQL在运行时才启动其他服务器监控
                if (mySqlRunning)
                {
                    MySqlMonitor.StartMonitoring(OnLog, UpdateStatusDisplay);
                    Thread.Sleep(1000);
                    worldWatcher.Start();
                    realmWatcher.Start();

                    OnLog("MangosRestarter 启动并开始监控...");
                    UpdateStatusDisplay();
                }
                else
                {
                    OnLog("[ERROR] MySQL未运行，程序无法启动服务器监控");
                }
            }
            catch (Exception ex)
            {
                Logger.Write($"程序启动失败: {ex}");
                MessageBox.Show($"程序启动失败: {ex.Message}", "错误",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                Hide();
            }
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                Hide();
            }
        }
    }
}